package com.fowo.api.syncAmazon.api;

import cn.hutool.core.date.DateUtil;
import com.amazon.spapi.api.ReportsApi;
import com.amazon.spapi.model.reports.CreateReportSpecification;
import com.amazon.spapi.model.reports.Report;
import com.amazon.spapi.model.reports.ReportDocument;
import com.amazon.spapi.model.reports.ReportOptions;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.service.DatainterfaceAuthorityService;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.entity.TmpStockTaking;
import com.fowo.api.service.impl.ShopInfoServiceImpl;
import com.fowo.api.service.impl.TmpStockTakingServiceImpl;
import com.fowo.api.syncAmazon.util.AmazonUtil;
import com.fowo.api.syncAmazon.util.AmzDateUtils;
import com.fowo.api.syncAmazon.util.GeneralUtil;
import com.squareup.okhttp.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.zip.GZIPInputStream;

@Component
@Slf4j
public class StockTakingReportService extends ReportService {

    @Resource
    private DatainterfaceAuthorityService datainterfaceAuthorityBaseService;
    @Resource
    private AmazonUtil amazonUtil;
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    @Resource
    private TmpStockTakingServiceImpl tmpStockTakingService;

    /**
     * 盘存 数据
     * @throws Exception
     */
    public void getStockTaking() throws Exception {
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"Amazon"), false);

        final List<ShopInfo> list = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01"));
        for(ShopInfo shop : list){

            List<String> marketplaceIds = Arrays.asList(shop.getMarketplaceId().split(","));

            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType("GET_LEDGER_DETAIL_VIEW_DATA");
            body.setMarketplaceIds(marketplaceIds);
            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.beginOfDay(DateUtil.yesterday())));
            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.endOfDay(DateUtil.yesterday())));

//            Calendar cstart=Calendar.getInstance();
//            cstart.add(Calendar.DATE, -360);
//            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(cstart));
//            Calendar cend=Calendar.getInstance();
//            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(cend));

            ReportOptions reportOptions = new ReportOptions();
            reportOptions.put("eventType","Adjustments");
            body.setReportOptions(reportOptions);

            // 第一步 创建报告
            ReportsApi reportsApi = amazonUtil.getReportsApi(entityAuthority,shop,0.0167);
            final String reportId = createReport(reportsApi, body);
            // 第二步 检验报告是否完成
            ReportsApi reportsApi2 = amazonUtil.getReportsApi(entityAuthority,shop,2.0);
            final Report report = getReport(reportsApi2, reportId);
            // 第三步 获取报告连接
            ReportsApi reportsApi3 = amazonUtil.getReportsApi(entityAuthority,shop,0.0167);
            final ReportDocument reportDocument = reportsApi3.getReportDocument(report.getReportDocumentId());
            // 第四步 下载报告
            String compressionAlgorithm = null;
            if(null != reportDocument.getCompressionAlgorithm()){
                compressionAlgorithm = reportDocument.getCompressionAlgorithm().getValue();
            }
            download(reportDocument.getUrl(),compressionAlgorithm,shop);

        }
    }

    @Override
    public void download(String url, String compressionAlgorithm, ShopInfo shop) throws IOException, IllegalArgumentException {
        OkHttpClient httpclient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        Response response = httpclient.newCall(request).execute();
        if (!response.isSuccessful()) {
            System.out.println(
                    String.format("Call to download content was unsuccessful with response code: %d and message: %s",
                            response.code(), response.message()));
            return;
        }

        try (ResponseBody responseBody = response.body()) {
            MediaType mediaType = MediaType.parse(response.header("Content-Type"));
            Charset charset = mediaType.charset();
//            if (charset == null) {
//                throw new IllegalArgumentException(String.format(
//                        "Could not parse character set from '%s'", mediaType.toString()));
//            }

            Closeable closeThis = null;
            try {
                InputStream inputStream = responseBody.byteStream();
                closeThis = inputStream;

                if ("GZIP".equals(compressionAlgorithm)) {
                    inputStream = new GZIPInputStream(inputStream);
                    closeThis = inputStream;
                }

                // This example assumes that the download content has a charset in the content-type header, e.g.
                // text/plain; charset=UTF-8
                if ("text".equals(mediaType.type()) && "plain".equals(mediaType.subtype())) {
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                    closeThis = inputStreamReader;

                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    closeThis = reader;

                    int lineNumber = 0;
                    String line;
                    Map<String,Integer> titleList = new HashMap<String,Integer>();
                    List<TmpStockTaking> list = new ArrayList<>();
                    while ((line = reader.readLine()) != null) {
                        String[] info = line.replaceAll("\"","").split("\t");
                        int length = info.length;
                        if (lineNumber == 0) {
                            for (int i = 0; i < length; i++) {
                                titleList.put(info[i],i);
                            }
                        } else {
                            TmpStockTaking tmp = new TmpStockTaking();
                            tmp.setCreateTime(new Date());
                            String report_date= GeneralUtil.getStrValue(info, titleList, "Date");
                            String fnsku= GeneralUtil.getStrValue(info, titleList, "FNSKU");
                            String asin= GeneralUtil.getStrValue(info, titleList, "ASIN");
                            String sku= GeneralUtil.getStrValue(info, titleList, "MSKU");
                            String title= GeneralUtil.getStrValue(info, titleList, "Title");
                            String event_type= GeneralUtil.getStrValue(info, titleList, "Event Type");
                            String reference_id= GeneralUtil.getStrValue(info, titleList, "Reference ID");
                            Integer quantity = GeneralUtil.getIntegerValue(info, titleList, "Quantity");
                            String fulfillment_center = GeneralUtil.getStrValue(info, titleList, "Fulfillment Center");
                            String disposition= GeneralUtil.getStrValue(info, titleList, "Disposition");
                            String reason= GeneralUtil.getStrValue(info, titleList, "Reason");
                            String country= GeneralUtil.getStrValue(info, titleList, "Country");
                            Integer reconciled_quantity= GeneralUtil.getIntegerValue(info, titleList, "Reconciled Quantity");
                            Integer unreconciled_quantity= GeneralUtil.getIntegerValue(info, titleList, "Unreconciled Quantity");
                            String dateAndTime= GeneralUtil.getStrValue(info, titleList, "Date and Time");


                            tmp.setSid(shop.getId());
                            tmp.setRegion(shop.getRegion());
                            tmp.setCountry(shop.getMid());
                            tmp.setReportDate(AmzDateUtils.getDatePlus(dateAndTime));
                            tmp.setFnsku(fnsku);
                            tmp.setAsin(asin);
                            tmp.setMsku(sku);
                            tmp.setTitle(title);
                            tmp.setEventType(event_type);
                            tmp.setReferenceId(reference_id);
                            tmp.setQuantity(quantity);
                            tmp.setFulfillmentCenter(fulfillment_center);
                            tmp.setDisposition(disposition);
                            tmp.setReason(reason);
                            tmp.setReasonText(AmzDateUtils.getReasonText(reason));
                            tmp.setCountryCode(country);
                            tmp.setReconciledQuantity(reconciled_quantity);
                            tmp.setUnreconciledQuantity(unreconciled_quantity);

                            list.add(tmp);
                        }
                        lineNumber++;
                        // Process line by line.
                    }
                    tmpStockTakingService.saveBatch(list);
                } else {
                    //Handle content with binary data/other media types here.
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.error("处理盘存数据异常",e);
            } finally {
                if (closeThis != null) {
                    closeThis.close();
                }
            }
        }
    }
}
